/*******************************************************************************
* This is the header file that describes the system properties.
*
* Author: Kong Wai Weng
* Email:  waiweng83@gmail.com
*******************************************************************************/



#ifndef _SYSTEM_H
#define _SYSTEM_H



// Instruction cycle frequency.
#define	FCY			40000000

// Include Microchip Library.
#include <p33FJ256GP710a.h>
#include <libpic30.h>



// Default UART baud rate.
#define UART1_BAUD		19200		// GPS.
#define UART2_BAUD		57600		// PC / Telemetry.



// RTOS Stack error watermark threshold.
#define RTOS_STACK_THRESHOLD	100



// IO Connections.
#define LED1			LATEbits.LATE0
#define LED2			LATEbits.LATE1
#define LED3			LATEbits.LATE2

#define TESTPOINT		LATBbits.LATB8

#define PUSH_BUTTON		PORTEbits.RE3

#define OUT1			LATDbits.LATD0
#define OUT2			LATDbits.LATD1
#define OUT3			LATDbits.LATD2
#define OUT4			LATDbits.LATD3
#define OUT5			LATDbits.LATD4
#define OUT6			LATDbits.LATD5
#define OUT7			LATDbits.LATD6
#define OUT8			LATDbits.LATD7

#define RCRX1			PORTDbits.RD8
#define RCRX2			PORTDbits.RD9
#define RCRX3			PORTDbits.RD10
#define RCRX4			PORTDbits.RD11
#define RCRX5			PORTDbits.RD12
#define RCRX6			PORTDbits.RD13
#define RCRX7			PORTDbits.RD14
#define RCRX8			PORTDbits.RD15



#define BMP085_EOC		PORTAbits.RA4
#define SFLASH_CSN		LATAbits.LATA5

#define I2C1_SDA		PORTGbits.RG3
#define I2C1_SCL		PORTGbits.RG2
#define I2C2_SDA		PORTAbits.RA3
#define I2C2_SCL		PORTAbits.RA2

#define I2C1_SDA_TRIS           TRISGbits.TRISG3
#define I2C1_SCL_TRIS           TRISGbits.TRISG2
#define I2C2_SDA_TRIS           TRISAbits.TRISA3
#define I2C2_SCL_TRIS           TRISAbits.TRISA2



// PI.
#define PI                      3.14159265f

// Scale to convert radian to degree.
#define RAD_TO_DEG              (180.0f / PI)

// Scale to convert degree to radian.
#define DEG_TO_RAD		(PI / 180.0f)

// Scale to convert knots to m/s.
#define KNOTS_TO_MS		(463.0f / 900.0f)

// Scale to convert m/s to km/h.
#define MS_TO_KMH		3.6f

// Gravity (m/s)
#define GRAVITY			9.80665f

// The current time zone.
#define TIME_ZONE		+8

// Magnetic Inclination (rad).
#define MAG_INCL		-0.10879219f

// Magnetic Declination (rad).
#define MAG_DECL		-0.005235988f

// Scale to convert GPS coordinate in deg to distance.
#define COORD_DEG_TO_DIST	111194.9266f

// Specific gas constant for dry air.
#define R_SPECIFIC              287.058f



// Pulse width value for 500us.
#define PULSE_WIDTH_500		2500

// Pulse width value for 750us.
#define PULSE_WIDTH_750		3750

// Pulse width value for 1000us.
#define PULSE_WIDTH_1000	5000

// Pulse width value for 1250us.
#define PULSE_WIDTH_1250	6250

// Pulse width value for 1500us.
#define PULSE_WIDTH_1500	7500

// Pulse width value for 1750us.
#define PULSE_WIDTH_1750	8750

// Pulse width value for 2000us.
#define PULSE_WIDTH_2000	10000

// Pulse width value for 2250us.
#define PULSE_WIDTH_2250	11250

// Pulse width value for 2500us.
#define PULSE_WIDTH_2500	12500



// RC Rx Channel.
#define RUDDER_CHANNEL		1
#define ELEVATOR_CHANNEL	2
#define THROTTLE_CHANNEL	3
#define AILERON_CHANNEL		4
#define LEFT_AILERON_CHANNEL	4
#define RIGHT_AILERON_CHANNEL	6
#define MODE_CHANNEL		5


// RC Rx Polarity.
#define RUDDER_DIR		-1
#define ELEVATOR_DIR		-1
#define THROTTLE_DIR		-1
#define AILERON_DIR		-1



// Offset when the UAV is level (rad).
#define ROLL_OFFSET		(0.5f * DEG_TO_RAD)
#define PITCH_OFFSET		(6.0f * DEG_TO_RAD)



// Maximum turn rate (rad/s).
#define MAX_TURN_RATE		(50.0f * DEG_TO_RAD)

// Maximum bank angle (rad).
#define MAX_ROLL		(60.0f * DEG_TO_RAD)

// Maximum positive and negative pitch angle (rad).
#define MAX_POS_PITCH		(20.0f * DEG_TO_RAD)
#define MAX_NEG_PITCH		(10.0f * DEG_TO_RAD)

// Pitch offset for roll compensation.
#define PITCH_ROLL_COMP		0.2f

// Minimum distance to waypoint before we switch to the next one (m).
#define MIN_DISTANCE		20.0f

// The radius for loiter (m).
//#define LOITER_RADIUS			100.0f

// The distance from the loiter radius to start loitering (m).
#define LOITER_RANGE		100.0f

// Loiter direction.
// 1 = CW, -1 = CCW.
//#define LOITER_DIR			1.0f

// The maximum entry angle for crosstrack.
#define CROSSTRACK_OFFSET_MAX	(45.0f * DEG_TO_RAD)



// Some useful utilities.

// Set the lower and upper limit.
#define LIMIT(i, l, u)	((i < l)? l : ((i > u)? u : i))



// Convert the angle to 0 - 2PI rad.
#define CONVERT_0_2PI(x) {		\
	while (x > (2.0f * PI)) {	\
		x -= 2.0f * PI;			\
	}							\
	while (x < 0.0f) {			\
		x += 2.0f * PI;			\
	}							\
} (void) 0;



// Convert the angle to +-PI rad.
#define CONVERT_NEGPI_PI(x) {		\
	while (x > PI) {			\
		x -= 2.0f * PI;			\
	}							\
	while (x < -PI) {			\
		x += 2.0f * PI;			\
	}							\
} (void) 0;



// Temporary disable the interrupt while excecuting the specified code.
#define INTERRUPT_PROTECT(x) {			\
	char saved_ipl;						\
	SET_AND_SAVE_CPU_IPL(saved_ipl,7);	\
	x;									\
	RESTORE_CPU_IPL(saved_ipl);			\
} (void) 0;



#endif
